package cn.kilo.domain.service.order.impl;

import cn.kilo.domain.model.order.entity.StaffEntity;
import cn.kilo.domain.model.order.vo.OrderStatusVO;
import cn.kilo.domain.service.order.AbstractStaffStrategyChain;
import cn.kilo.domain.model.order.entity.OrderEntity;
import cn.kilo.domain.service.order.factory.DefaultFactory;
import cn.kilo.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author kilok
 * 分拣员1
 */

@Slf4j
@Component("sorter1")
public class Sorter1Strategy extends AbstractStaffStrategyChain {
    @Override
    public DefaultFactory.Role getRole() {
        return DefaultFactory.Role.SORTER1;
    }

    @Override
    public Map<String, Integer> getLeftStaff(OrderEntity order) {
        return repository.getSorter1Staff(order);
    }

    @Override
    public boolean beStaff(StaffEntity staffEntity) {
        boolean res =repository.checkStaff(staffEntity);
        if(res) {
            return false;
        }
        return repository.beSorter1(staffEntity);
    }


    /**
     * 分拣员-1接单 开始第一次计时
     *
     * @param order orderId sorter1Id
     * @return5
     */
    @Override
    public List<OrderStatusVO> doJob(OrderEntity order) {
        ReentrantLock lock=new ReentrantLock();
        try {
            boolean b = lock.tryLock(4, TimeUnit.SECONDS);
            if(b) {
                Integer number = order.getNumber();
                List<OrderStatusVO> orderByNumber = repository.getOrderByNumber(number, order.getRidgepole());
                List<OrderStatusVO> ans = new ArrayList<>();
                for (OrderStatusVO orderStatus : orderByNumber) {
                    //获取对应订单的锁并删除该订单所在列表的订单信息
                    Boolean res = repository.takeOder(orderStatus.getOrderId(), order.getRidgepole());
                    StaffEntity staff = repository.queryStaffById(order.getSorter1());
                    if (res) {
                        //开始计时并将对应订单放入对应的骑手列表下
                        String cacheKey = Constants.RedisKey.ORDER_INFO + Constants.UNDERLINE + orderStatus.getOrderId();
                        OrderStatusVO orderStatusVO = repository.getOrderStatusEntity(cacheKey);

                        String staffKey = Constants.RedisKey.STAFF_ORDER + Constants.UNDERLINE + order.getSorter1() + Constants.UNDERLINE + orderStatusVO.getRidgepole();

                        log.info("cache: orderStatusVO:{}", orderStatusVO);

                        orderStatusVO.setStaffName(staff.getStaffName());
                        orderStatusVO.setNow(LocalDateTime.now());
                        orderStatusVO.setStatus(DefaultFactory.Status.TAKE_1.getInfo());
                        orderStatusVO.setStatusCode(DefaultFactory.Status.TAKE_1.getCode());

                        log.info("更新订单状态:{}", orderStatusVO);
                        ans.add(orderStatusVO);
                        repository.updateOrder(orderStatusVO, staffKey, order.getSorter1());
                    }
                }
                return ans;
            }
           return null;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }
}
